package com.ipan.poi.easyexcel;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.poi.poifs.filesystem.FileMagic;

import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.StringUtils;

/**
 * Excel文件类型枚举
 * 
 * 重写ExcelTypeEnum是为了自动纠正.xls与.xlsx多了x或少了x的情况;
 * 
 * @author iPan
 * @version 2022-12-26
 */
public enum MyExcelTypeEnum {
    /**
     * csv
     */
    CSV(".csv"),
    /**
     * xls
     */
    XLS(".xls"),
    /**
     * xlsx
     */
    XLSX(".xlsx");

    private String value;

    MyExcelTypeEnum(String value) {
        this.setValue(value);
    }

    public static MyExcelTypeEnum valueOf(ReadWorkbook readWorkbook) {
        ExcelTypeEnum excelType = readWorkbook.getExcelType();
        if (excelType != null) {
            switch(excelType.getValue()) {
	            case ".csv":
	            	return MyExcelTypeEnum.CSV;
	            case ".xls":
	            	return MyExcelTypeEnum.XLS;
	            case ".xlsx":
	            	return MyExcelTypeEnum.XLSX;
            }
        }
        File file = readWorkbook.getFile();
        InputStream inputStream = readWorkbook.getInputStream();
        if (file == null && inputStream == null) {
            throw new ExcelAnalysisException("File and inputStream must be a non-null.");
        }
        try {
            if (file != null) {
                if (!file.exists()) {
                    throw new ExcelAnalysisException("File " + file.getAbsolutePath() + " not exists.");
                }
                // If there is a password, use the FileMagic first
                if (!StringUtils.isEmpty(readWorkbook.getPassword())) {
                    try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file))) {
                        return recognitionExcelType(bufferedInputStream);
                    }
                }
                // Use the name to determine the type
                String fileName = file.getName();
//                if (fileName.endsWith(XLSX.getValue())) {
//                    return XLSX;
//                } else if (fileName.endsWith(XLS.getValue())) {
//                    return XLS;
//                } else 
                if (fileName.endsWith(CSV.getValue())) { // CSV一般不会错，直接可以根据后缀判断；
                    return CSV;
                }
                // 下面使用文件流去判断真实的文件类型
//                if (StringUtils.isEmpty(readWorkbook.getPassword())) {
                    try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file))) {
                        return recognitionExcelType(bufferedInputStream);
                    }
//                }
            }
            if (!inputStream.markSupported()) {
                inputStream = new BufferedInputStream(inputStream);
                readWorkbook.setInputStream(inputStream);
            }
            return recognitionExcelType(inputStream);
        } catch (ExcelCommonException e) {
            throw e;
        } catch (Exception e) {
            throw new ExcelCommonException(
                "Convert excel format exception.You can try specifying the 'excelType' yourself", e);
        }
    }

    private static MyExcelTypeEnum recognitionExcelType(InputStream inputStream) throws Exception {
        FileMagic fileMagic = FileMagic.valueOf(inputStream);
        if (FileMagic.OLE2.equals(fileMagic)) {
            return XLS;
        }
        if (FileMagic.OOXML.equals(fileMagic)) {
            return XLSX;
        }
        throw new ExcelCommonException(
            "Convert excel format exception.You can try specifying the 'excelType' yourself");
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
    
}
